package com.atguigu.tingshu.album.task;

import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author: atguigu
 * @create: 2025-07-30 10:23
 */
@Slf4j
@Component
public class RebuildBloomFilterTask {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AlbumInfoService albumInfoService;

    /**
     * 每月1日凌晨2点或项目维护期间：
     * 重建/扩容布隆过滤器
     */
    @Scheduled(cron = "0 0 2 1 * ?")
    //@Scheduled(cron = "0/5 * * * * ?")
    public void rebuildBloomFilter() {
        //1.获取到原有布隆过滤器对象 得到配置信息：期望数据量，现有数量预估值，误判率
        RBloomFilter<Long> oldBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        long count = oldBloomFilter.count();
        long expectedInsertions = oldBloomFilter.getExpectedInsertions();
        double falseProbability = oldBloomFilter.getFalseProbability();

        //2.如果现有数量预估值大于期望数据规模，进行扩容
        if (count >= expectedInsertions) {
            log.info("布隆过滤器已满，开始扩容");
            //2.1 新建布隆过滤器对象，初始化配置信息不变
            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
            newBloomFilter.tryInit(expectedInsertions * 2, falseProbability);

            //2.2 将现有过审专辑ID添加到新布隆过滤器对象中
            List<Long> albumIdList = albumInfoService.findAlbumListByStatus(SystemConstant.ALBUM_STATUS_PASS);
            for (Long albumId : albumIdList) {
                newBloomFilter.add(albumId);
            }
            //2.3 删除旧布隆过滤器对象（配置&位图）
            oldBloomFilter.delete();

            //2.4 重命名布隆过滤器，改为原有名称
            newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
            log.info("扩容结束");
        } else {
            log.info("开始重建布隆过滤器");
            //3.如果现有数量预估值小于期望数据规模，进行重建
            //3.1 新建布隆过滤器对象，初始化配置信息不变
            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
            newBloomFilter.tryInit(expectedInsertions, falseProbability);

            //3.2 将现有过审专辑ID添加到新布隆过滤器对象中
            List<Long> albumIdList = albumInfoService.findAlbumListByStatus(SystemConstant.ALBUM_STATUS_PASS);
            for (Long albumId : albumIdList) {
                newBloomFilter.add(albumId);
            }
            //3.3 删除旧布隆过滤器对象（配置&位图）
            oldBloomFilter.delete();

            //3.4 重命名布隆过滤器，改为原有名称
            newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
            log.info("重建布隆过滤器结束");
        }

    }


}
